<?php
/**
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace builder\form_step\util\step;

use builder\base\Builder;
use builder\base\UndefinedParamsException;
use builder\base\ViewBuilderInterface;
use yii\base\InvalidArgumentException;

/**
 * 项内容
 * @author cleverstone
 * @since ym2.0
 */
class Item extends SiType
{
    /**
     * @var array
     */
    private $_options = [
        'title' => '',
        'content' => '',
        'callId' => '',
    ];

    /**
     * 步标题
     * @param string $title
     * @return $this
     */
    public function title($title)
    {
        $this->_options['title'] = (string)$title;
        return $this;
    }

    /**
     * 设置调用ID(用于JS表单数据获取; 即:挂载在JS对象[ym2PageDataExport]中的方法名称,内置表单构建器ID已自动挂载;)
     * 在步内容设置时,如果传入的[结果]是字符串,如需[下一步]校验和表单数据获取,则需要调用该方法,并传入挂载在JS对象[ym2PageDataExport]中的方法名称;
     * @param string $callId
     * @return $this
     */
    public function callId($callId)
    {
        $this->_options['callId'] = (string)$callId;
        return $this;
    }

    /**
     * 步内容
     * @param string|\Closure|Builder $content
     * @return $this
     * @throws UndefinedParamsException
     * @throws \ReflectionException
     */
    public function content($content)
    {
        if ($content instanceof \Closure) {
            $reflectionFunc = new \ReflectionFunction($content);

            $depend = [];
            foreach($reflectionFunc->getParameters() as $value) {
                if ($value->isDefaultValueAvailable()){
                    $depend[] = $value->getDefaultValue();
                } else {
                    if (PHP_VERSION_ID >= 80000) {
                        $c = $value->getType();
                        $isClass = false;
                        if ($c instanceof \ReflectionNamedType) {
                            $isClass = !$c->isBuiltin();
                        }

                        $class = $isClass ? (new \ReflectionClass($c->getName())) : null;
                    } else {
                        $class = $value->getClass();
                    }
                    if (!is_null($class)) {
                        $object = $class->newInstance();
                        if ($object instanceof Builder) {
                            $depend[] = $object;
                            //设置callId
                            if (empty($this->_options['callId'])) {
                                $this->_options['callId'] = $object->id;
                            }

                        } else {
                            throw new UndefinedParamsException("Function parameters {$class} is not supported. ");
                        }

                        continue;
                    }

                    $depend[] = null;
                }
            }

            $content = call_user_func_array($content, $depend);
        }

        if (empty($this->_options['callId']) && $content instanceof Builder) {
            //设置callId
            $this->_options['callId'] = $content->id;
        }

        if ($content instanceof ViewBuilderInterface) {
            $content = $content->render(true);
        }

        if (!is_string($content)) {
            throw new InvalidArgumentException('Expected parameter [content] is string, But the others are given. ');
        }

        $this->_options['content'] = $content;
        return $this;
    }

    /**
     * @return array
     */
    public function _toArray()
    {
        return $this->_options;
    }
}